package model

import (
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"gitee.com/liumou_site/gcs"
	"gitee.com/liumou_site/gf"
)

// setConf 方法用于读取并设置配置信息。
// 该方法会尝试从指定的配置文件中加载配置，并根据配置文件的内容设置 Info 结构体的相关字段。
// 如果配置文件不存在或加载失败，则记录错误并返回。
func (i Info) setConf() {
	// 检查配置文件是否存在，如果存在则加载配置。
	f := gf.NewFile("/etc/ssh-guardian/config.toml")
	f.IsFile()
	if f.IsFiles {
		// 加载配置文件并处理可能的错误。
		config, err := LoadConfig("/etc/ssh-guardian/config.toml")
		if err != nil {
			GetLanguageManager().Error("配置文件错误: ", "Config file error:", err.Error())
			os.Exit(1)
		}

		// 根据配置文件内容设置 Info 结构体的字段。
		i.Source = config.Paths.Source
		i.Target = config.Paths.BackupDir
		if config.Service.IsDefault {
			i.Default = true
		}
		i.Port = config.Service.ListenPort
		i.Debug = config.Logging.Debug
		i.China = true
		i.Interval = config.Service.Interval
		if i.Debug {
			GetLanguageManager().Debug("正在使用配置文件进行配置", "Using configuration file for configuration")
			GetLanguageManager().Debug("检测间隔为：", "Check interval:", i.Interval)
			GetLanguageManager().Debug("设置监听端口为：", "Set listening port:", i.Port)
			GetLanguageManager().Debug("设置备份路径为：", "Set backup path:", i.Target)
			GetLanguageManager().Debug("是否属于默认安装的配置文件：", "Is the default installation configuration file:", i.Default)
		}
		if strings.EqualFold(config.Logging.Language, "en") {
			i.China = false
		}
	} else {
		GetLanguageManager().Error("未检测到配置文件，请检查配置文件是否存在: ", "No configuration file detected, please check if the configuration file exists: ", f.FileName)
	}
}

// Start 函数用于启动一个服务，该服务负责从源路径复制文件到目标路径，并确保SSH服务的正常运行。
// 参数说明：
//   - source: 源路径，表示需要复制的文件或目录的路径。
//   - target: 目标路径，表示文件或目录将被复制到的路径。
//   - port: 服务监听的端口号。
//   - sec: 检查服务状态的间隔时间（秒）。
//   - debug: 是否启用调试模式，启用后会输出更多日志信息。
//   - china: 是否为中国地区，用于决定日志的语言和默认配置。
//   - useToml: 是否使用TOML配置文件进行参数设置。
//   - InitConf: 是否初始化配置文件。
func Start(source, target string, port, sec int, debug, china, useToml, InitConf bool) {
	// 获取语言管理器
	langManager := GetLanguageManager()

	// 创建一个新的Info结构体实例，并设置其源路径和目标路径。
	i := new(Info)
	i.Cmd = gcs.NewShell()
	i.Source = source
	i.Target = target
	i.Port = port
	i.Debug = debug
	i.Interval = sec
	i.Exit = false
	i.China = china
	i.Default = IsDefault(china, debug)
	if i.Default {
		if debug {
			langManager.Debug("正在使用默认配置文件进行配置", "Using default configuration file for configuration")
		}
		i.Source = "/etc/ssh"
	}
	f := gf.NewFile("/etc/ssh-guardian/config.toml")
	f.IsFile()

	langManager.Info("当前设置源路径为：", "Current source path set to:", i.Source)
	if !f.IsFiles {
		langManager.Debug("未检测到配置文件，正在初始化配置文件", "Not detected configuration file, initializing configuration file")
		i.InitConfig()
		os.Exit(0)
	}
	if useToml {
		i.setConf() // 读取配置文件并进行参数设置。
		if debug {
			i.Debug = true
		}
	}
	if InitConf {
		langManager.Debug("正在初始化配置文件", "Initializing configuration file")
		i.InitConfig()
		// 初始化完成后直接退出，不执行后续的服务创建和备份操作
		langManager.Info("初始化配置完成", "Initialization configuration completed")
		os.Exit(0)
	}

	i.Dst = i.Target
	if !i.Default {
		i.Dst = filepath.Join(i.Target, "openssh")
	}

	// 服务注册权限检查：只有初始化模式或服务未注册时才允许注册
	shouldRegisterService := InitConf || !IsServiceRegistered()

	if shouldRegisterService {
		if !InitConf && IsServiceRegistered() {
			langManager.Info("检测到服务已存在，跳过注册步骤", "Service already registered, skipping registration")
		} else {
			langManager.Info("正在执行服务注册流程", "Executing service registration process")
			// 创建并启动服务，如果失败则记录错误并返回。
			err := CreateSshGuardianService(i)
			if err != nil {
				langManager.Error("创建服务失败: ", "Create service failed:", err)
				os.Exit(6)
			}
		}
	} else {
		langManager.Info("服务已注册，跳过服务注册步骤，运行SSH服务管理逻辑", "Service already registered, skipping registration, running SSH service management logic")
	}

	// 根据默认配置或自定义配置执行备份操作。
	if i.Default {
		langManager.Debug("正在执行默认备份", "Executing default backup")
		err := i.DefaultBackupStart()
		if err != nil {
			os.Exit(7)
		}
	} else {
		langManager.Debug("正在执行自定义备份", "Executing custom backup")
		// 检查源路径是否存在且有效，如果无效则记录错误并返回。
		err := i.CheckSourcePath()
		if err != nil {
			langManager.Error("源路径无效，请检查源路径是否正确:", "Source path error:", err)
			os.Exit(4)
		}
		// 执行备份操作，如果备份失败则记录错误并退出程序。
		err = i.CheckAndCopyBackup()
		if err != nil {
			langManager.Error("备份失败: ", "Backup failed:", err)
			os.Exit(5)
		}
	}
	if i.Exit {
		os.Exit(0)
	}

	// 无限循环，持续检查SSH服务状态，并在必要时进行恢复和重启。
	// 注意：这里只能管理sshd服务，不能管理ssh-guardian自身服务
	for {
		// 检查SSH服务是否正常，如果正常则返回，否则尝试恢复SSH服务并重启。
		err := CheckAndRestartService(i)
		if err == nil {
			if i.Debug {
				langManager.Debug("SSH服务正在运行正常", "SSH service is running normally")
				langManager.Debug("等待"+strconv.Itoa(i.Interval)+"秒后重新检查SSH服务状态", "Wait "+strconv.Itoa(i.Interval)+" seconds before checking the SSH service status again")
			}
			time.Sleep(time.Duration(sec) * time.Second)
			continue
		}
		langManager.Error("SSH服务重启失败,正在进行服务重置", "SSH service restart failed, resetting service")
		err = MkdirRun()
		if err != nil {
			langManager.Error("运行目录创建失败: ", "Run directory creation failed:", err)
			os.Exit(11)
		}

		// 根据默认配置或自定义配置恢复SSH服务。
		if i.Default {
			err = i.RestoreSSHDefaultStart()
			if err != nil {
				langManager.Error("SSH服务恢复失败: ", "SSH service recovery failed:", err)
				os.Exit(2)
			}
		} else {
			// 尝试恢复SSH服务并重启，如果失败则记录错误并返回。
			err = i.RestoreSSH()
			if err != nil {
				langManager.Error("SSH服务恢复失败: ", "SSH service recovery failed:", err)
				os.Exit(3)
			}
		}

		// 创建并启动SSH服务，如果失败则记录错误并返回。
		err = i.CreateSshService()
		if err != nil {
			os.Exit(8)
		}
		if !IsDefault(china, debug) {
			// 创建符号链接，如果失败则记录错误并返回。
			err = i.CreateSymlink()
			if err != nil {
				os.Exit(9)
			}
		}
		// 重启服务，如果失败则记录错误并返回。
		err = i.RestartSshdService()
		if err != nil {
			os.Exit(10)
		}

		// 记录服务恢复成功的日志信息。
		langManager.Info("SSH服务恢复成功", "SSH service recovery successful")
		if i.Debug {
			langManager.Debug("等待"+strconv.Itoa(i.Interval)+"秒后重新检查SSH服务状态", "Wait "+strconv.Itoa(i.Interval)+" seconds before checking the SSH service status again")
		}
		time.Sleep(time.Duration(i.Interval) * time.Second)
	}
}
